/**  http://include-media.com/documentation/#mixin-media
	@include media('>phone') { }

	@include media('>phone', '<=tablet') { }

	@include media('>=358px', '<850px') { }

	@include media('>desktop', '<=1350px') { }

	@include media('retina2x') { }

	@include media('>=350px', '<tablet', 'retina3x') { }

**/
/**
	@include media-context(('custom': 678px), ('all': 'all')) {
  		.foo {
    		@include media('all', '>phone', '<=custom') {
    		 // ...
    		}
 	 	}
	}
**/
$breakpoints: (
		'phone': 320px,
		'tablet': 768px,
		'desktop': 1024px
) !default;
$media-expressions: (
		'screen': 'screen',
		'print': 'print',
		'handheld': 'handheld',
		'landscape': '(orientation: landscape)',
		'portrait': '(orientation: portrait)',
		'retina2x': '(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi)',
		'retina3x': '(-webkit-min-device-pixel-ratio: 3), (min-resolution: 350dpi)'
) !default;
$unit-intervals: (
		'px': 1,
		'em': 0.01,
		'rem': 0.1
) !default;
$im-media-support: true !default;
$im-no-media-breakpoint: 'desktop' !default;
$im-no-media-expressions: ('screen', 'portrait', 'landscape') !default;
@function log($message) {
  @if feature-exists('at-error') {
	@error $message;
  } @else {
	@warn $message;
	$_: noop();
  }

  @return $message;
}
@mixin log($message) {
  @if log($message) {}
}
@function noop() {}
@function im-intercepts-static-breakpoint($conditions...) {
  $no-media-breakpoint-value: map-get($breakpoints, $im-no-media-breakpoint);

  @if not $no-media-breakpoint-value {
	@if log('`#{$im-no-media-breakpoint}` is not a valid breakpoint.') {}
  }

  @each $condition in $conditions {
	@if not map-has-key($media-expressions, $condition) {
	  $operator: get-expression-operator($condition);
	  $prefix: get-expression-prefix($operator);
	  $value: get-expression-value($condition, $operator);
	  @if ($prefix == 'max' and $value <= $no-media-breakpoint-value) or
          ($prefix == 'min' and $value > $no-media-breakpoint-value) {
		@return false;
	  }
	} @else if not index($im-no-media-expressions, $condition) {
	  @return false;
	}
  }

  @return true;
}
@function get-expression-operator($expression) {
  @each $operator in ('>=', '>', '<=', '<', '≥', '≤') {
	@if str-index($expression, $operator) {
	  @return $operator;
	}
  }
  $_: log('No operator found in `#{$expression}`.');
}
@function get-expression-dimension($expression, $operator) {
  $operator-index: str-index($expression, $operator);
  $parsed-dimension: str-slice($expression, 0, $operator-index - 1);
  $dimension: 'width';

  @if str-length($parsed-dimension) > 0 {
	$dimension: $parsed-dimension;
  }

  @return $dimension;
}
@function get-expression-prefix($operator) {
  @return if(index(('<', '<=', '≤'), $operator), 'max', 'min');
}
@function get-expression-value($expression, $operator) {
  $operator-index: str-index($expression, $operator);
  $value: str-slice($expression, $operator-index + str-length($operator));

  @if map-has-key($breakpoints, $value) {
	$value: map-get($breakpoints, $value);
  } @else {
	$value: to-number($value);
  }

  $interval: map-get($unit-intervals, unit($value));

  @if not $interval {
	$_: log('Unknown unit `#{unit($value)}`.');
  }

  @if $operator == '>' {
	$value: $value + $interval;
  } @else if $operator == '<' {
	$value: $value - $interval;
  }

  @return $value;
}
@function parse-expression($expression) {
  @if map-has-key($media-expressions, $expression) {
	@return map-get($media-expressions, $expression);
  }

  $operator: get-expression-operator($expression);
  $dimension: get-expression-dimension($expression, $operator);
  $prefix: get-expression-prefix($operator);
  $value: get-expression-value($expression, $operator);

  @return '(#{$prefix}-#{$dimension}: #{$value})';
}
@function slice($list, $start: 1, $end: length($list)) {
  @if length($list) < 1 or $start > $end {
	@return ();
  }

  $result: ();

  @for $i from $start through $end {
	$result: append($result, nth($list, $i));
  }

  @return $result;
}
@function to-number($value) {
  @if type-of($value) == 'number' {
	@return $value;
  } @else if type-of($value) != 'string' {
	$_: log('Value for `to-number` should be a number or a string.');
  }

  $result: 0;
  $digits: 0;
  $minus: str-slice($value, 1, 1) == '-';
  $numbers: ('0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9);

  @for $i from if($minus, 2, 1) through str-length($value) {
	$character: str-slice($value, $i, $i);

	@if not (index(map-keys($numbers), $character) or $character == '.') {
	  @return to-length(if($minus, -$result, $result), str-slice($value, $i))
	}

	@if $character == '.' {
	  $digits: 1;
	} @else if $digits == 0 {
	  $result: $result * 10 + map-get($numbers, $character);
	} @else {
	  $digits: $digits * 10;
	  $result: $result + map-get($numbers, $character) / $digits;
	}
  }

  @return if($minus, -$result, $result);
}
@function to-length($value, $unit) {
  $units: ('px': 1px, 'cm': 1cm, 'mm': 1mm, '%': 1%, 'ch': 1ch, 'pc': 1pc, 'in': 1in, 'em': 1em, 'rem': 1rem, 'pt': 1pt, 'ex': 1ex, 'vw': 1vw, 'vh': 1vh, 'vmin': 1vmin, 'vmax': 1vmax);

  @if not index(map-keys($units), $unit) {
	$_: log('Invalid unit `#{$unit}`.');
  }

  @return $value * map-get($units, $unit);
}
@mixin media-context($tweakpoints: (), $tweak-media-expressions: ()) {
  $global-breakpoints: $breakpoints;
  $global-media-expressions: $media-expressions;
  $breakpoints: map-merge($breakpoints, $tweakpoints) !global;
  $media-expressions: map-merge($media-expressions, $tweak-media-expressions) !global;

  @content;
  $breakpoints: $global-breakpoints !global;
  $media-expressions: $global-media-expressions !global;
}
@mixin media($conditions...) {
  // scss-lint:disable SpaceAroundOperator
  @if ($im-media-support and length($conditions) == 0) or
      (not $im-media-support and im-intercepts-static-breakpoint($conditions...)) {
	@content;
  } @else if ($im-media-support and length($conditions) > 0) {
	@media #{unquote(parse-expression(nth($conditions, 1)))} {
	  // Recursive call
	  @include media(slice($conditions, 2)...) {
	  @content;
	}
	}
  }
}